<template>
  <!-- 计时面板 -->
  <view class="countdown-timer">
    <uni-countdown
      class="mr-20"
      v-if="hasTimer"
      ref="countdownRef"
      :show-day="false"
      :show-hour="false"
      :minute="countdown[0]"
      :second="countdown[1]"
      :key="factorial"
      @timeup="timeup"
    ></uni-countdown>
    <view>血量&nbsp;&nbsp;{{ factorial - wrongNum }}</view>
  </view>
  <view class="mofang-panel" :style="{ gap: gap * 2 + 'rpx' }">
    <!-- 魔方墙1 -->
    <view class="mf-item" v-if="first.length > 0">
      <view
        v-for="(item, index) in first"
        :class="['mf-fact', checkCorrect(index) === index ? 'is-correct' : '']"
        :style="{ width: (1 / factorial) * 100 + '%' }"
        @tap="selectMo(index)"
      >
        <!-- 元魔方 -->
        <view
          v-for="i in item"
          class="mf-meta"
          :style="{ width: (1 / 3) * 100 + '%', backgroundColor: i }"
        ></view>
      </view>
    </view>
    <!-- 空 加载状态 -->
    <view class="mf-item cuIcon-loading2 cuIconfont-spin" v-else></view>
    <!-- 魔方墙2 -->
    <view class="mf-item" v-if="second.length > 0">
      <view
        v-for="(item, index) in second"
        :class="['mf-fact', checkCorrect(index) === index ? 'is-correct' : '']"
        :style="{ width: (1 / factorial) * 100 + '%' }"
        @tap="selectMo(index)"
      >
        <!-- 元魔方 -->
        <view
          v-for="i in item"
          class="mf-meta"
          :style="{ width: (1 / 3) * 100 + '%', backgroundColor: i }"
        ></view>
      </view>
    </view>
    <!-- 空 加载状态 -->
    <view class="mf-item cuIcon-loading2 cuIconfont-spin" v-else></view>
  </view>
</template>

<script setup>
import { computed, nextTick, ref, watch } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import {
  generateMate,
  generateRandomNumber,
  getRandomColorExcept
} from '@/utils/index.js'
import { cloneDeep } from 'lodash-es'

const props = defineProps({
  // 间隙
  gap: {
    type: Number,
    default: 30
  },
  // 阶 2-8
  factorial: {
    type: Number,
    default: 8
  },
  // 倒计时 [分, 秒]
  countdown: {
    type: Array,
    default: [3, 0]
  },
  hasTimer: {
    type: Boolean,
    default: true
  }
})

const emits = defineEmits(['select', 'correct', 'refresh', 'answer', 'fail'])

const colors = ['red', 'yellow', 'blue', 'green', 'white', 'orange'] // 红、黄、蓝、绿、白、橙
const differentCorrect = ref(null) // 正确的不同索引
const differentMetaCorrect = ref(null) // 不同的元魔方索引
const differentSelected = ref(null) // 用户选择的索引
const isCorrect = ref(false) // 是否正确
const first = ref([])
const second = ref([])
const wrongNum = ref(0) // 错误次数大于阶数时判定为失败
const isWrong = computed(() => wrongNum.value >= props.factorial)

onLoad(() => {
  nextTick(() => {
    refresh()
  })
})

watch(() => props.factorial, refresh)

// 刷新
function refresh() {
  const { factorial } = props
  isCorrect.value = false
  differentCorrect.value = generateRandomNumber(factorial * factorial)
  differentSelected.value = null
  wrongNum.value = 0
  restartTimer()

  emits('refresh', differentCorrect.value)

  generateMo()
}

// 借一条命，再战
function again() {
  restartTimer()
  wrongNum.value = 0
}

// 生成魔方
function generateMo() {
  const { factorial } = props
  const factNum = factorial * factorial
  let result = []

  for (let i = 0; i < factNum; i++) {
    result[i] = generateMate(colors, 9)
  }

  first.value = result

  const copyResult = cloneDeep(result)
  // 不同的元色块索引
  differentMetaCorrect.value = generateRandomNumber(9)
  // first原色块
  const firstColor = copyResult[differentCorrect.value][differentMetaCorrect.value]
  // second不同色块（在colors中随机找一个和firstColor不一样的色块）
  const secondColor = getRandomColorExcept(colors, firstColor)
  copyResult[differentCorrect.value][differentMetaCorrect.value] = secondColor
  second.value = copyResult

  emits('answer', [differentCorrect.value, differentMetaCorrect.value])
}

// 点击查找
function selectMo(index) {
  if (isCorrect.value) return // 已经找出正确
  if (timeover.value) return // 时间已过
  if (isWrong.value) return // 已失败

  differentSelected.value = index

  if (
    differentSelected.value === differentCorrect.value &&
    differentSelected.value === index
  ) {
    // 成功
    isCorrect.value = true
    emits('correct', {
      correct: true,
      factorial: props.factorial,
      answer: [differentCorrect.value, differentMetaCorrect.value]
    })
  } else {
    // 错误
    wrongNum.value++
    if (isWrong.value) {
      emits('fail', {
        type: 'wrong',
        fail: true,
        factorial: props.factorial,
        answer: [differentCorrect.value, differentMetaCorrect.value]
      })
    }
  }

  emits('select', index)
}

// 检查是否正确
function checkCorrect(index) {
  if (
    differentSelected.value === differentCorrect.value &&
    differentSelected.value === index
  ) {
    return index
  }
  return false
}

/**
 * 倒计时
 */
const countdownRef = ref()
const timeover = ref(false)
function timeup() {
  timeover.value = true
  if (isWrong.value) return

  emits('fail', {
    type: 'timeup',
    fail: true,
    factorial: props.factorial,
    answer: [differentCorrect.value, differentMetaCorrect.value]
  })
}

function restartTimer() {
  timeover.value = false
  countdownRef.value?.update()
}

defineExpose({
  refresh,
  again
})
</script>

<style lang="scss">
.countdown-timer {
  margin-bottom: 20rpx;
  height: 20px;
  font-size: 12px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mofang-panel {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  align-items: center;
  position: relative;

  .mf-item {
    flex: 1;
    max-width: 1400rpx;
    aspect-ratio: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;

    &.is-empty {
    }

    .mf-fact {
      aspect-ratio: 1;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-wrap: wrap;
      box-shadow: 0 0 0 1px #00000099;
      position: relative;

      &.is-correct {
        transform: scale(1.25);
        z-index: 9;
        &::after {
          content: '';
          position: absolute;
          width: 140%;
          height: 140%;
          border-radius: 50%;
          border: 16rpx solid rgba(0, 0, 0, 0.6);
          z-index: 1;
        }
      }

      .mf-meta {
        aspect-ratio: 1;
        box-shadow: 0 0 0 1px #cccccc66;
      }
    }
  }
}

/* 宽屏 */
@media screen and (min-width: 768px) {
  .mofang-panel {
    flex-direction: row;
  }
}
</style>
